use serde::{Serialize, Deserialize};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, SystemTime};
use tokio::sync::RwLock;
use rustcloud_core::{CircuitBreakerState, ServiceResult};

/// 熔断器性能监控器
pub struct CircuitBreakerMonitor {
    /// 服务监控数据
    service_monitors: Arc<RwLock<HashMap<String, ServiceMonitor>>>,
    /// 监控配置
    config: MonitorConfig,
}

/// 监控配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MonitorConfig {
    /// 指标保留时间
    pub metrics_retention: Duration,
    /// 聚合间隔
    pub aggregation_interval: Duration,
    /// 历史窗口大小
    pub history_window_size: usize,
}

impl Default for MonitorConfig {
    fn default() -> Self {
        Self {
            metrics_retention: Duration::from_secs(3600), // 1小时
            aggregation_interval: Duration::from_secs(60), // 1分钟
            history_window_size: 100,
        }
    }
}

/// 单个服务的监控数据
#[derive(Debug, Clone)]
struct ServiceMonitor {
    /// 服务名称
    service_name: String,
    /// 当前状态
    current_state: CircuitBreakerState,
    /// 状态历史
    state_history: Vec<StateChange>,
    /// 请求指标历史
    request_metrics: Vec<RequestMetrics>,
    /// 最后更新时间
    last_updated: SystemTime,
}

/// 状态变化记录
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StateChange {
    /// 旧状态
    pub from_state: CircuitBreakerState,
    /// 新状态
    pub to_state: CircuitBreakerState,
    /// 变化时间
    pub timestamp: SystemTime,
    /// 变化原因
    pub reason: String,
}

/// 请求指标
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RequestMetrics {
    /// 时间戳
    pub timestamp: SystemTime,
    /// 总请求数
    pub total_requests: u64,
    /// 成功请求数
    pub successful_requests: u64,
    /// 失败请求数
    pub failed_requests: u64,
    /// 平均响应时间
    pub avg_response_time: Duration,
    /// 最大响应时间
    pub max_response_time: Duration,
    /// 最小响应时间
    pub min_response_time: Duration,
    /// 成功率
    pub success_rate: f64,
    /// 当前并发数
    pub concurrent_requests: u32,
}

/// 聚合统计数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AggregatedStats {
    /// 服务名称
    pub service_name: String,
    /// 统计时间范围
    pub time_range: TimeRange,
    /// 总请求数
    pub total_requests: u64,
    /// 成功请求数
    pub successful_requests: u64,
    /// 失败请求数
    pub failed_requests: u64,
    /// 平均成功率
    pub avg_success_rate: f64,
    /// 平均响应时间
    pub avg_response_time: Duration,
    /// 99分位响应时间
    pub p99_response_time: Duration,
    /// 状态分布
    pub state_distribution: HashMap<CircuitBreakerState, Duration>,
    /// 熔断次数
    pub circuit_breaker_trips: u32,
    /// 恢复次数
    pub recovery_count: u32,
}

/// 时间范围
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TimeRange {
    pub start: SystemTime,
    pub end: SystemTime,
}

impl CircuitBreakerMonitor {
    pub fn new(config: MonitorConfig) -> Self {
        Self {
            service_monitors: Arc::new(RwLock::new(HashMap::new())),
            config,
        }
    }

    /// 记录状态变化
    pub async fn record_state_change(
        &self,
        service_name: &str,
        from_state: CircuitBreakerState,
        to_state: CircuitBreakerState,
        reason: String,
    ) {
        let mut monitors = self.service_monitors.write().await;
        let monitor = monitors.entry(service_name.to_string())
            .or_insert_with(|| ServiceMonitor::new(service_name.to_string()));

        monitor.current_state = to_state;
        monitor.state_history.push(StateChange {
            from_state,
            to_state,
            timestamp: SystemTime::now(),
            reason,
        });

        // 保持历史大小
        if monitor.state_history.len() > self.config.history_window_size {
            monitor.state_history.remove(0);
        }

        monitor.last_updated = SystemTime::now();
    }

    /// 记录请求指标
    pub async fn record_request_metrics(&self, service_name: &str, metrics: RequestMetrics) {
        let mut monitors = self.service_monitors.write().await;
        let monitor = monitors.entry(service_name.to_string())
            .or_insert_with(|| ServiceMonitor::new(service_name.to_string()));

        monitor.request_metrics.push(metrics);

        // 保持历史大小
        if monitor.request_metrics.len() > self.config.history_window_size {
            monitor.request_metrics.remove(0);
        }

        monitor.last_updated = SystemTime::now();
    }

    /// 获取服务的当前状态
    pub async fn get_current_state(&self, service_name: &str) -> Option<CircuitBreakerState> {
        let monitors = self.service_monitors.read().await;
        monitors.get(service_name).map(|m| m.current_state)
    }

    /// 获取服务的状态历史
    pub async fn get_state_history(&self, service_name: &str) -> Vec<StateChange> {
        let monitors = self.service_monitors.read().await;
        monitors.get(service_name)
            .map(|m| m.state_history.clone())
            .unwrap_or_default()
    }

    /// 获取聚合统计数据
    pub async fn get_aggregated_stats(
        &self,
        service_name: &str,
        time_range: TimeRange,
    ) -> ServiceResult<AggregatedStats> {
        let monitors = self.service_monitors.read().await;
        
        if let Some(monitor) = monitors.get(service_name) {
            let filtered_metrics: Vec<&RequestMetrics> = monitor.request_metrics
                .iter()
                .filter(|m| m.timestamp >= time_range.start && m.timestamp <= time_range.end)
                .collect();

            if filtered_metrics.is_empty() {
                return Ok(AggregatedStats {
                    service_name: service_name.to_string(),
                    time_range,
                    total_requests: 0,
                    successful_requests: 0,
                    failed_requests: 0,
                    avg_success_rate: 0.0,
                    avg_response_time: Duration::from_millis(0),
                    p99_response_time: Duration::from_millis(0),
                    state_distribution: HashMap::new(),
                    circuit_breaker_trips: 0,
                    recovery_count: 0,
                });
            }

            // 计算聚合数据
            let total_requests = filtered_metrics.iter().map(|m| m.total_requests).sum();
            let successful_requests = filtered_metrics.iter().map(|m| m.successful_requests).sum();
            let failed_requests = filtered_metrics.iter().map(|m| m.failed_requests).sum();

            let avg_success_rate = filtered_metrics.iter()
                .map(|m| m.success_rate)
                .sum::<f64>() / filtered_metrics.len() as f64;

            let avg_response_time = Duration::from_millis(
                filtered_metrics.iter()
                    .map(|m| m.avg_response_time.as_millis() as u64)
                    .sum::<u64>() / filtered_metrics.len() as u64
            );

            // 计算99分位响应时间
            let mut response_times: Vec<Duration> = filtered_metrics.iter()
                .map(|m| m.avg_response_time)
                .collect();
            response_times.sort();
            let p99_index = (response_times.len() as f64 * 0.99) as usize;
            let p99_response_time = response_times.get(p99_index.min(response_times.len() - 1))
                .copied()
                .unwrap_or(Duration::from_millis(0));

            // 计算状态分布
            let mut state_distribution = HashMap::new();
            let mut last_timestamp = time_range.start;
            let mut last_state = CircuitBreakerState::Closed;

            for state_change in &monitor.state_history {
                if state_change.timestamp >= time_range.start && state_change.timestamp <= time_range.end {
                    if let Ok(duration) = state_change.timestamp.duration_since(last_timestamp) {
                        *state_distribution.entry(last_state).or_insert(Duration::from_millis(0)) += duration;
                    }
                    last_timestamp = state_change.timestamp;
                    last_state = state_change.to_state;
                }
            }

            // 计算熔断和恢复次数
            let circuit_breaker_trips = monitor.state_history.iter()
                .filter(|sc| sc.to_state == CircuitBreakerState::Open)
                .count() as u32;

            let recovery_count = monitor.state_history.iter()
                .filter(|sc| sc.to_state == CircuitBreakerState::Closed)
                .count() as u32;

            Ok(AggregatedStats {
                service_name: service_name.to_string(),
                time_range,
                total_requests,
                successful_requests,
                failed_requests,
                avg_success_rate,
                avg_response_time,
                p99_response_time,
                state_distribution,
                circuit_breaker_trips,
                recovery_count,
            })
        } else {
            Err(rustcloud_core::ServiceError::ServiceNotFound(
                format!("Service '{}' not found in monitor", service_name)
            ))
        }
    }

    /// 获取所有监控的服务名称
    pub async fn get_monitored_services(&self) -> Vec<String> {
        let monitors = self.service_monitors.read().await;
        monitors.keys().cloned().collect()
    }

    /// 清理过期数据
    pub async fn cleanup_expired_data(&self) {
        let now = SystemTime::now();
        let mut monitors = self.service_monitors.write().await;

        for (_, monitor) in monitors.iter_mut() {
            // 清理过期的状态历史
            monitor.state_history.retain(|sc| {
                now.duration_since(sc.timestamp).unwrap_or(Duration::from_secs(0)) < self.config.metrics_retention
            });

            // 清理过期的请求指标
            monitor.request_metrics.retain(|rm| {
                now.duration_since(rm.timestamp).unwrap_or(Duration::from_secs(0)) < self.config.metrics_retention
            });
        }

        // 移除完全过期的服务监控
        monitors.retain(|_, monitor| {
            now.duration_since(monitor.last_updated).unwrap_or(Duration::from_secs(0)) < self.config.metrics_retention
        });
    }

    /// 生成健康度报告
    pub async fn generate_health_report(&self) -> HashMap<String, HealthReport> {
        let monitors = self.service_monitors.read().await;
        let mut reports = HashMap::new();

        for (service_name, monitor) in monitors.iter() {
            let health_score = self.calculate_health_score(monitor).await;
            let recent_metrics = monitor.request_metrics.last().cloned();
            
            reports.insert(service_name.clone(), HealthReport {
                service_name: service_name.clone(),
                current_state: monitor.current_state,
                health_score,
                recent_metrics,
                last_state_change: monitor.state_history.last().cloned(),
            });
        }

        reports
    }

    /// 计算健康度得分 (0.0 - 1.0)
    async fn calculate_health_score(&self, monitor: &ServiceMonitor) -> f64 {
        if let Some(recent_metrics) = monitor.request_metrics.last() {
            let success_rate_score = recent_metrics.success_rate;
            
            let response_time_score = if recent_metrics.avg_response_time > Duration::from_millis(1000) {
                0.5
            } else if recent_metrics.avg_response_time < Duration::from_millis(200) {
                1.0
            } else {
                1.0 - (recent_metrics.avg_response_time.as_millis() as f64 / 1000.0).min(0.5)
            };

            let state_score = match monitor.current_state {
                CircuitBreakerState::Closed => 1.0,
                CircuitBreakerState::HalfOpen => 0.7,
                CircuitBreakerState::Open => 0.0,
            };

            // 加权平均
            (success_rate_score * 0.5 + response_time_score * 0.3 + state_score * 0.2).min(1.0).max(0.0)
        } else {
            0.5 // 没有数据时返回中等健康度
        }
    }
}

impl ServiceMonitor {
    fn new(service_name: String) -> Self {
        Self {
            service_name,
            current_state: CircuitBreakerState::Closed,
            state_history: Vec::new(),
            request_metrics: Vec::new(),
            last_updated: SystemTime::now(),
        }
    }
}

/// 健康度报告
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthReport {
    pub service_name: String,
    pub current_state: CircuitBreakerState,
    pub health_score: f64,
    pub recent_metrics: Option<RequestMetrics>,
    pub last_state_change: Option<StateChange>,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_monitor_state_changes() {
        let monitor = CircuitBreakerMonitor::new(MonitorConfig::default());
        
        // 记录状态变化
        monitor.record_state_change(
            "test-service",
            CircuitBreakerState::Closed,
            CircuitBreakerState::Open,
            "Failed threshold exceeded".to_string(),
        ).await;

        // 验证状态
        let current_state = monitor.get_current_state("test-service").await;
        assert_eq!(current_state, Some(CircuitBreakerState::Open));

        // 验证历史
        let history = monitor.get_state_history("test-service").await;
        assert_eq!(history.len(), 1);
        assert_eq!(history[0].to_state, CircuitBreakerState::Open);
    }

    #[tokio::test]
    async fn test_aggregated_stats() {
        let monitor = CircuitBreakerMonitor::new(MonitorConfig::default());
        let service_name = "test-service";
        let now = SystemTime::now();

        // 记录一些请求指标
        for i in 0..5 {
            let metrics = RequestMetrics {
                timestamp: now,
                total_requests: 10,
                successful_requests: 8 + i % 2,
                failed_requests: 2 - i % 2,
                avg_response_time: Duration::from_millis(100 + i * 10),
                max_response_time: Duration::from_millis(200),
                min_response_time: Duration::from_millis(50),
                success_rate: (8.0 + (i % 2) as f64) / 10.0,
                concurrent_requests: 5,
            };
            
            monitor.record_request_metrics(service_name, metrics).await;
        }

        // 获取聚合统计
        let time_range = TimeRange {
            start: now - Duration::from_secs(60),
            end: now + Duration::from_secs(60),
        };

        let stats = monitor.get_aggregated_stats(service_name, time_range).await.unwrap();
        assert_eq!(stats.total_requests, 50); // 5 * 10
        assert!(stats.avg_success_rate > 0.8);
    }
}